#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTimer>
#include <QMessageBox>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
#include <qtextcodec.h>
#include <QClipboard>

int counter;

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    codec = QTextCodec::codecForName("UTF-8");
    m_nowTcpRecData = "(034000000700001B20004C00000043D8980000A7)";

    QTimer *timer = new QTimer();
    timer->start(1000);
    m_tcpRecCounter = 0;
    m_uartRecCounter =0;
    connect(timer, &QTimer::timeout, this, [this](){
        ui->l_tcpRecSpeed->setText(QString::number(m_tcpRecCounter));
        ui->l_uartRecSpeed->setText(QString::number(m_uartRecCounter));
        m_tcpRecCounter=0;m_uartRecCounter=0;
    });

    m_serialPortToVirtual = new QSerialPort();
    m_serialPortToReg = new QSerialPort();
    tcpSock1 = new QTcpSocket(this);
    connect(tcpSock1, &QTcpSocket::readyRead, this, &MainWindow::tcpSocket1RecServer);
//    connect(tcpServer, &QWebSocket::SocketError, this,SLOT(displayError(QAbstractSocket::SocketError)));
    connect(tcpSock1, &QTcpSocket::connected, this, [this](){ui->btnConnect->setText("disconnect");ui->btnOpen_toReg->setEnabled(false);});
    connect(tcpSock1, &QTcpSocket::disconnected, this, [this](){ui->btnConnect->setText("connect");ui->btnOpen_toReg->setEnabled(true);});
}

MainWindow::~MainWindow()
{
    tcpSock1->abort();
    delete ui;
}

void MainWindow::newConnect()
{
    tcpSock1->abort();
    tcpSock1->connectToHost(ui->urlText->text(), ui->cb_port->currentText().toUInt());
}

void MainWindow::tcpSocket1RecServer()
{
    QByteArray msg = tcpSock1->readAll();
    m_tcpRecCounter++;
//    MainSerialRecvData += msg;
    int t_rightIndex = msg.lastIndexOf(')');
    int t_leftIndex = msg.lastIndexOf('(',t_rightIndex);
    QByteArray msg2 = msg.mid(t_leftIndex, t_rightIndex-t_leftIndex+1);
//    qDebug()<<msg2;
    excTcpDateAnalyze(msg2);
    if(m_serialPortToVirtual->isOpen()) m_serialPortToVirtual->write(msg);
    if(ui->cb_tcpText->isChecked()) ui->tcpRecText->appendPlainText(msg);
}

void MainWindow::UartPortToVirRecServer()
{
    QByteArray RecvBuf = m_serialPortToVirtual->readAll();
    if(RecvBuf.isEmpty()) return;
    m_uartRecCounter++;
    //analyze
//    int t_rightIndex = RecvBuf.lastIndexOf(')');
//    int t_leftIndex = RecvBuf.lastIndexOf('(',t_rightIndex);
//    QByteArray msg2 = RecvBuf.mid(t_leftIndex, t_rightIndex-t_leftIndex+1);
//    excUartDateAnalyze(msg2);
//    tcpSock1RecvData += RecvBuf;
    if(tcpSock1->isOpen()) tcpSock1->write(RecvBuf);
    if(m_serialPortToReg->isOpen()) {m_serialPortToReg->write(RecvBuf);qDebug()<<"o";}
    if(ui->cb_uartText->isChecked()) ui->uartRecText->appendPlainText(RecvBuf);
}

void MainWindow::on_btnScan_clicked()
{
    /* 新建串口类 */
//    m_serialPortToVirtual = new QSerialPort();
    ui->comboBox->clear();
    if(m_serialPortToVirtual != NULL)
    {
        /* 查找可用串口 */
        foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
        {
            QSerialPort serial;
            serial.setPort(info);
            /* 判断端口是否能打开 */
            if(serial.open(QIODevice::ReadWrite))
            {
                int isHaveItemInList = 0;
                /* 判断是不是已经在列表中了 */
                for(int i=0; i<ui->comboBox->count(); i++)
                {
                    /* 如果，已经在列表中了，那么不添加这一项了就 */
                    if(ui->comboBox->itemData(i) == serial.portName())
                    {
                        isHaveItemInList++;
                    }
                }

                if(isHaveItemInList == 0)
                {
                    ui->comboBox->addItem(serial.portName());
                }
                serial.close();
            }
        }
    }
    else
    {
        // 串口没有初始化成功，先不处理异常
        // 警告对话框
        QMessageBox::warning(this,tr("警告"),
                             tr("串口没有初始化成功"),QMessageBox::Ok);
    }
}

void MainWindow::on_btnOpen_clicked()
{
    /* 先来判断对象是不是为空 */
    if(m_serialPortToVirtual == NULL)
    {
        /* 新建串口对象 */
        m_serialPortToVirtual = new QSerialPort();
    }
    /* 判断是要打开串口，还是关闭串口 */
    if(m_serialPortToVirtual->isOpen())
    {
        /* 串口已经打开，现在来关闭串口 */
        m_serialPortToVirtual->close();
        ui->tcpRecText->setPlainText(codec->toUnicode("串口在关闭状态"));
        ui->btnOpen->setText(tr("open"));
    }
    else
    {
        /* 判断是否有可用串口 */
        if(ui->comboBox->count() != 0)
        {
            /* 串口已经关闭，现在来打开串口 */
            /* 设置串口名称 */
            m_serialPortToVirtual->setPortName(ui->comboBox->currentText());
            /* 设置波特率 */
            m_serialPortToVirtual->setBaudRate(115200);
            /* 设置数据位数 */
            m_serialPortToVirtual->setDataBits(QSerialPort::Data8);
            /* 设置奇偶校验 */
            m_serialPortToVirtual->setParity(QSerialPort::EvenParity);
            /* 设置停止位 */
            m_serialPortToVirtual->setStopBits(QSerialPort::OneStop);
            /* 设置流控制 */
            m_serialPortToVirtual->setFlowControl(QSerialPort::NoFlowControl);
            /* 打开串口 */
            m_serialPortToVirtual->open(QIODevice::ReadWrite);
            /* 设置串口缓冲区大小，这里必须设置为这么大 */
            m_serialPortToVirtual->setReadBufferSize(50);
            /* 注册回调函数 */
            QObject::connect(m_serialPortToVirtual, &QSerialPort::readyRead, this, &MainWindow::UartPortToVirRecServer);

//            qDebug()<<codec->toUnicode("串口在关闭状态，现在打开了") + ui->comboBox->currentText();
//            qDebug()<<tr("show();");

            ui->tcpRecText->setPlainText(codec->toUnicode("串口在打开状态"));
            ui->btnOpen->setText(tr("close"));
        }
        else
        {
            qDebug()<<"没有可用串口，请重新常识扫描串口";
            // 警告对话框
            QMessageBox::warning(this,tr("警告"),tr("没有可用串口，请重新尝试扫描串口！"),QMessageBox::Ok);
        }
    }
}

void MainWindow::on_btnConnect_clicked()
{
//    qDebug()<<"one";
    if(ui->btnConnect->text().contains("disconnect"))tcpSock1->disconnectFromHost();
    else newConnect();
}

void MainWindow::excUartDateAnalyze(QByteArray i_date)
{
    m_nowTcpRecData.clear();
    m_nowTcpRecData = i_date;
    if(!ui->cb_analyze_uart->isChecked()) return;
    if(i_date.length()<=42 && i_date.length()>=46) {return;}
    bool ok;
    ui->label_1->setText(QString::number((double)(short)i_date.mid(11,4).toUShort(&ok, 16)/100,'f',2));
    ui->label_2->setText(QString::number((double)(short)i_date.mid(11+4,4).toUShort(&ok, 16)/100,'f',2));
    ui->label_3->setText(QString::number((double)(short)i_date.mid(11+2*4,4).toUShort(&ok, 16)/100,'f',2));
    ui->label_4->setText(QString::number((double)(short)i_date.mid(11+3*4,4).toUShort(&ok, 16)/100,'f',2));
    ui->label_5->setText(QString::number((double)(short)i_date.mid(11+4*4,4).toUShort(&ok, 16)/100,'f',2));
    ui->label_6->setText(QString::number((double)(short)i_date.mid(11+5*4,4).toUShort(&ok, 16)/100,'f',2));
    ui->label_6->setText(QString::number((double)(short)i_date.mid(11+5*4,4).toUShort(&ok, 16)/100,'f',2));
//    qDebug()<<(double)i_date.mid(11+5*4,4).toUShort(&ok, 16)<<(short)i_date.mid(11+5*4,4).toUShort(&ok, 16);
}

void MainWindow::excTcpDateAnalyze(QByteArray i_date)
{
//    qDebug()<<i_date;
    m_nowTcpRecData.clear();
    m_nowTcpRecData = i_date;
    if(!ui->cb_analize->isChecked()) {return;}
    if(i_date.length()<=42 && i_date.length()>=46) {return;}
    bool ok;
    ui->label_1->setText(QString::number((double)(short)i_date.mid(11,4).toUShort(&ok, 16)/100,'f',2));
    ui->label_2->setText(QString::number((double)(short)i_date.mid(11+4,4).toUShort(&ok, 16)/100,'f',2));
    ui->label_3->setText(QString::number((double)(short)i_date.mid(11+2*4,4).toUShort(&ok, 16)/100,'f',2));
    ui->label_4->setText(QString::number((double)(short)i_date.mid(11+3*4,4).toUShort(&ok, 16)/100,'f',2));
    ui->label_5->setText(QString::number((double)(short)i_date.mid(11+4*4,4).toUShort(&ok, 16)/100,'f',2));
    ui->label_6->setText(QString::number((double)(short)i_date.mid(11+5*4,4).toUShort(&ok, 16)/100,'f',2));
//    ui->label_6->setText(QString::number((double)(short)i_date.mid(11+5*4,4).toUShort(&ok, 16)/100,'f',2));
//    qDebug()<<i_date<<i_date.mid(11,4)<<i_date.mid(11+4,4);
}

void MainWindow::on_btn_copy4_clicked()
{
    QClipboard *clipboard = QApplication::clipboard();
    bool ok;
    clipboard->setText(QString::number((double)(short)m_nowTcpRecData.mid(11,4).toUShort(&ok, 16)/100,'f',2)+'\t'+
                       QString::number((double)(short)m_nowTcpRecData.mid(11+1*4,4).toUShort(&ok, 16)/100,'f',2)+'\t'+
                       QString::number((double)(short)m_nowTcpRecData.mid(11+2*4,4).toUShort(&ok, 16)/100,'f',2)+'\t'+
                       QString::number((double)(short)m_nowTcpRecData.mid(11+3*4,4).toUShort(&ok, 16)/100,'f',2)+'\t'+
                       QString::number((double)(short)m_nowTcpRecData.mid(11+4*4,4).toUShort(&ok, 16)/100,'f',2));
}

void MainWindow::on_btn_copy5_clicked()
{
    QClipboard *clipboard = QApplication::clipboard();
    bool ok;
    clipboard->setText(QString::number((double)(short)m_nowTcpRecData.mid(11,4).toUShort(&ok, 16)/100,'f',2)+'\t'+
                       QString::number((double)(short)m_nowTcpRecData.mid(11+1*4,4).toUShort(&ok, 16)/100,'f',2)+'\t'+
                       QString::number((double)(short)m_nowTcpRecData.mid(11+2*4,4).toUShort(&ok, 16)/100,'f',2)+'\t'+
                       QString::number((double)(short)m_nowTcpRecData.mid(11+3*4,4).toUShort(&ok, 16)/100,'f',2));
}

void MainWindow::on_btn_copy2_clicked()
{
    QClipboard *clipboard = QApplication::clipboard();
    bool ok;
    clipboard->setText(QString::number((double)(short)m_nowTcpRecData.mid(11+4*4,4).toUShort(&ok, 16)/100,'f',2)+'\t'+
                       QString::number((double)(short)m_nowTcpRecData.mid(11+5*4,4).toUShort(&ok, 16)/100,'f',2));
}

void MainWindow::on_btn_setug_clicked()
{
    ui->btn_setug->setEnabled(false);
    QByteArray t[5]={"(1041300001003404)","(1041310001003B38)",
                     "(1041320001003CB4)","(1041330001003DD8)",
                     "(1041340001004197)"};
    if(ui->cb_channel->currentIndex()==1)
    {
        t[0]="(1051300001003459)";
        t[1]="(1051310001003B65)";
        t[2]="(1051320001003CE9)";
        t[3]="(1051330001003D85)";
        t[4]="(10513400010041CA)";
    }

    if(tcpSock1->isOpen()) tcpSock1->write(t[0]);
    else if(m_serialPortToReg->isOpen()) m_serialPortToReg->write(t[0]);
    QTimer *t_timer = new QTimer;
    connect(t_timer, &QTimer::timeout, this, [this,t_timer,t](){
        static int i=0;
        i++;
        switch (i) {
        case 1:
            if(tcpSock1->isOpen()) tcpSock1->write(t[1]);
            else if(m_serialPortToReg->isOpen()) m_serialPortToReg->write(t[1]);
            break;
        case 2:
            if(tcpSock1->isOpen()) tcpSock1->write(t[2]);
            else if(m_serialPortToReg->isOpen()) m_serialPortToReg->write(t[2]);
            break;
        case 3:
            if(tcpSock1->isOpen()) tcpSock1->write(t[3]);
            else if(m_serialPortToReg->isOpen()) m_serialPortToReg->write(t[3]);
            break;
        case 4:
            if(tcpSock1->isOpen()) tcpSock1->write(t[4]);
            else if(m_serialPortToReg->isOpen()) m_serialPortToReg->write(t[4]);
            ui->btn_setug->setEnabled(true);
            break;
        default:
            i=0;
            t_timer->stop();
            break;
        }
    });
    t_timer->start(200);
}

void MainWindow::on_btn_setig_clicked()
{
    ui->btn_setig->setEnabled(false);
    QByteArray t[5]={"(104130000100360A)","(1041310001003E2D)",
                     "(1041320001003FAF)","(10413300010040F8)",
                     "(10413400010039C4)"};
    if(ui->cb_channel->currentIndex()==1)
    {
        t[0]="(1051300001003657)";
        t[1]="(1051310001003E70)";
        t[2]="(1051320001003FF2)";
        t[3]="(10513300010040A5)";
        t[4]="(1051340001003999)";
    }
    if(tcpSock1->isOpen()) tcpSock1->write(t[0]);
    else if(m_serialPortToReg->isOpen()) m_serialPortToReg->write(t[0]);
    QTimer *t_timer = new QTimer;
    connect(t_timer, &QTimer::timeout, this, [this,t_timer,t](){
        static int i=0;
        i++;
        switch (i) {
        case 1:
            if(tcpSock1->isOpen()) tcpSock1->write(t[1]);
            else if(m_serialPortToReg->isOpen()) m_serialPortToReg->write(t[1]);
            break;
        case 2:
            if(tcpSock1->isOpen()) tcpSock1->write(t[2]);
            else if(m_serialPortToReg->isOpen()) m_serialPortToReg->write(t[2]);
            break;
        case 3:
            if(tcpSock1->isOpen()) tcpSock1->write(t[3]);
            else if(m_serialPortToReg->isOpen()) m_serialPortToReg->write(t[3]);
            break;
        case 4:
            if(tcpSock1->isOpen()) tcpSock1->write(t[4]);
            else if(m_serialPortToReg->isOpen()) m_serialPortToReg->write(t[4]);
            ui->btn_setig->setEnabled(true);
            break;
        default:
            i=0;
            t_timer->stop();
            break;
        }
    });
    t_timer->start(200);
}

void MainWindow::on_btn_setstart_clicked()
{
    if(tcpSock1->isOpen())
    {
        if(ui->cb_channel->currentIndex()==0)tcpSock1->write("(104630000100007A)");
        else if(ui->cb_channel->currentIndex()==1)tcpSock1->write("(1056300001000027)");
        QTimer *t_timer = new QTimer;
        connect(t_timer, &QTimer::timeout, this, [this,t_timer](){
            t_timer->stop();
            if(ui->cb_channel->currentIndex()==0)tcpSock1->write("(104630000100017D)");
            else if(ui->cb_channel->currentIndex()==1)tcpSock1->write("(1056300001000120)");
        });
        t_timer->start(200);
    }
    else if(m_serialPortToReg->isOpen())
    {
        if(ui->cb_channel->currentIndex()==0)m_serialPortToReg->write("(104630000100007A)");
        else if(ui->cb_channel->currentIndex()==1)m_serialPortToReg->write("(1056300001000027)");
        QTimer *t_timer = new QTimer;
        connect(t_timer, &QTimer::timeout, this, [this,t_timer](){
            t_timer->stop();
            if(ui->cb_channel->currentIndex()==0)m_serialPortToReg->write("(104630000100017D)");
            else if(ui->cb_channel->currentIndex()==1)m_serialPortToReg->write("(1056300001000120)");
        });
        t_timer->start(200);
    }
}

void MainWindow::on_btn_setstop_clicked()
{
    if(tcpSock1->isOpen())
    {
        if(ui->cb_channel->currentIndex()==0)tcpSock1->write("(1046310001000003)");
        else if(ui->cb_channel->currentIndex()==1)tcpSock1->write("(105631000100005E)");
        QTimer *t_timer = new QTimer;
        connect(t_timer, &QTimer::timeout, this, [this,t_timer](){
            t_timer->stop();
            if(ui->cb_channel->currentIndex()==0)tcpSock1->write("(1046310001000104)");
            else if(ui->cb_channel->currentIndex()==1)tcpSock1->write("(1056310001000159)");
        });
        t_timer->start(200);
    }
    else if(m_serialPortToReg->isOpen())
    {
        if(ui->cb_channel->currentIndex()==0)m_serialPortToReg->write("(1046310001000003)");
        else if(ui->cb_channel->currentIndex()==1)m_serialPortToReg->write("(105631000100005E)");
        QTimer *t_timer = new QTimer;
        connect(t_timer, &QTimer::timeout, this, [this,t_timer](){
            t_timer->stop();
            if(ui->cb_channel->currentIndex()==0)m_serialPortToReg->write("(1046310001000104)");
            else if(ui->cb_channel->currentIndex()==1)m_serialPortToReg->write("(1056310001000159)");
        });
        t_timer->start(200);
    }
}

void MainWindow::on_btnScan_toReg_clicked()
{
    /* 新建串口类 */
//    m_serialPortToReg = new QSerialPort();
    ui->comboBox_toReg->clear();
    if(m_serialPortToReg != NULL)
    {
        /* 查找可用串口 */
        foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
        {
            QSerialPort serial;
            serial.setPort(info);
            /* 判断端口是否能打开 */
            if(serial.open(QIODevice::ReadWrite))
            {
                int isHaveItemInList = 0;
                /* 判断是不是已经在列表中了 */
                for(int i=0; i<ui->comboBox_toReg->count(); i++)
                {
                    /* 如果，已经在列表中了，那么不添加这一项了就 */
                    if(ui->comboBox_toReg->itemData(i) == serial.portName())
                    {
                        isHaveItemInList++;
                    }
                }

                if(isHaveItemInList == 0)
                {
                    ui->comboBox_toReg->addItem(serial.portName());
                }
                serial.close();
            }
        }
    }
    else
    {
        // 串口没有初始化成功，先不处理异常
        // 警告对话框
        QMessageBox::warning(this,tr("警告"),
                             tr("串口没有初始化成功"),QMessageBox::Ok);
    }
}

void MainWindow::on_btnOpen_toReg_clicked()
{
    /* 先来判断对象是不是为空 */
    if(m_serialPortToReg == NULL)
    {
        /* 新建串口对象 */
        m_serialPortToReg = new QSerialPort();
    }
    /* 判断是要打开串口，还是关闭串口 */
    if(m_serialPortToReg->isOpen())
    {
        /* 串口已经打开，现在来关闭串口 */
        m_serialPortToReg->close();
        ui->tcpRecText->setPlainText(codec->toUnicode("串口在关闭状态"));
        ui->btnOpen_toReg->setText(tr("open"));
        ui->btnConnect->setEnabled(true);
    }
    else
    {
        /* 判断是否有可用串口 */
        if(ui->comboBox_toReg->count() != 0)
        {
            /* 串口已经关闭，现在来打开串口 */
            /* 设置串口名称 */
            m_serialPortToReg->setPortName(ui->comboBox_toReg->currentText());
            /* 设置波特率 */
            m_serialPortToReg->setBaudRate(115200);
            /* 设置数据位数 */
            m_serialPortToReg->setDataBits(QSerialPort::Data8);
            /* 设置奇偶校验 */
            m_serialPortToReg->setParity(QSerialPort::EvenParity);
            /* 设置停止位 */
            m_serialPortToReg->setStopBits(QSerialPort::OneStop);
            /* 设置流控制 */
            m_serialPortToReg->setFlowControl(QSerialPort::NoFlowControl);
            /* 打开串口 */
            m_serialPortToReg->open(QIODevice::ReadWrite);
            /* 设置串口缓冲区大小，这里必须设置为这么大 */
            m_serialPortToReg->setReadBufferSize(50);
            /* 注册回调函数 */
            QObject::connect(m_serialPortToReg, &QSerialPort::readyRead, this, &MainWindow::UartPortToRegRecServer);

//            qDebug()<<codec->toUnicode("串口在关闭状态，现在打开了") + ui->comboBox_toReg->currentText();
//            qDebug()<<tr("show();");

            ui->tcpRecText->setPlainText(codec->toUnicode("串口在打开状态"));
            ui->btnOpen_toReg->setText(tr("close"));
            ui->btnConnect->setEnabled(false);
        }
        else
        {
            qDebug()<<"没有可用串口，请重新常识扫描串口";
            // 警告对话框
            QMessageBox::warning(this,tr("警告"),tr("没有可用串口，请重新尝试扫描串口！"),QMessageBox::Ok);
        }
    }
}

void MainWindow::UartPortToRegRecServer()
{
    static QByteArray s_buffer;
    QByteArray RecvBuf = m_serialPortToReg->readAll();
    if(RecvBuf.isEmpty()) return;
    else s_buffer+=RecvBuf;
    m_tcpRecCounter++;

    //analyze
    int t_rightIndex = s_buffer.lastIndexOf(')');
    int t_leftIndex = s_buffer.lastIndexOf('(',t_rightIndex);
    if(t_rightIndex==-1||t_leftIndex==-1) return;

    QByteArray msg2 = s_buffer.mid(t_leftIndex, t_rightIndex-t_leftIndex+1);
    excUartDateAnalyze(msg2);

    if(m_serialPortToVirtual->isOpen())
    {
        m_serialPortToVirtual->write(s_buffer.mid(0, t_rightIndex+1));
    }
    if(ui->cb_tcpText->isChecked()) ui->tcpRecText->appendPlainText(s_buffer.mid(0, t_rightIndex+1));
    s_buffer.remove(0,t_rightIndex+1);
}
